
export class Watcher<T>{
	static stack:Watcher<any>[]=[]
	static detectList:Watcher<any>[]=[]
	static activeWatcher(){
		return Watcher.stack[Watcher.stack.length - 1]
	}
	static update(){  //手动调
		if (this.detectList.length > 0) {
			var list = this.detectList.concat()
			for (var i = 0; i < list.length; i++) {
				var watcher = list[i]
				if (watcher.disposed) {
					this.detectList.splice(i, 1)
				} else {
					watcher.updateDetect()
				}
			}
		}
	}

	private _valueType: number = 0 //0 基础数据  1 监听函数
	private _value:T = null //如果 _valueType==0 读取这个数据
	private _valueFn: Function = null //如果 _valueType===1 读取这个数据
	private _notifyList:Watcher<any>[]=[]
	private _callBackList:Function[]=[]
	private _interVal = 1 //主动监测时用的
	private _interValCounter=0
	private disposed=false
  	constructor(baseValue:T | Function){
	 
		//如果baseValue 是一个watcher，转换成函数的形式
		if (baseValue instanceof Watcher) {
			var _b = baseValue
			baseValue = function () {
				return _b.get()
			}
		}
		if (typeof baseValue === 'function') {
			this._valueType = 1
			this._valueFn = baseValue
			this.calValue()
		} else {
			this._valueType = 0
			this._value = baseValue
		}
  	}

	set(value:T){
		if (this._valueType === 0) {
			this._setValue(value)
		} else {
			console.error('不要对计算watcher直接设置value', value)
		}
	}
	private _setValue(v:T){
		if (this._value === v) {
			return
		}
		this._value = v
		//触发事件
		var ll = this._callBackList.concat()
		for (var i = 0; i < ll.length; i++) {
			var cb = ll[i]
			if (typeof cb === 'function') {
				cb(this._value)
			} else {
				var index = this._callBackList.indexOf(cb)
				this._callBackList.splice(index, 1)
				
			}
		}

		//发送通知
		var l = this._notifyList.concat()
		l.forEach(function (w) {
			if (w.disposed) {
				var index = this._notifyList.indexOf(w)
				if (index >= 0) {
					this._notifyList.splice(index, 1)
				}
			} else {
				w.calValue()
			}
		}, this)
	}
	onChange(callback:Function,runNow=true){
		if (this.disposed) return
		if (this._callBackList.indexOf(callback) === -1) {
			this._callBackList.push(callback)
		}
		if (runNow) {
			callback(this._value)
		}
		return this
	}
	get():T{
		var w = Watcher.activeWatcher()
		if (w) {
			if (this._notifyList.indexOf(w) === -1) {
				this._notifyList.push(w)
			}
		}
		return this._value
	}
	private calValue=function(){
		if (this._valueType !== 1) {
			return
		}
		//计算属性  收集依赖
		Watcher.stack.push(this)
		var v = this._valueFn()
		Watcher.stack.pop()
		this._setValue(v)
	}
	//重新计算
	update(){
		this.calValue()
	}
	//开始主动监测 valueType 1的才能主动监测
	startDetect(interVal:number){
		if (this._valueType !== 1) return
		this._interVal = interVal || 1
		if (Watcher.detectList.indexOf(this) === -1) {
			Watcher.detectList.push(this)
		}
		return this
	}
	//停止主动监测
	stopDetect(){
		var index = Watcher.detectList.indexOf(this)
		if (index >= 0) {
			Watcher.detectList.splice(index, 1)
		}
	}
	updateDetect(){
		this._interValCounter++
		if (this._interValCounter >= this._interVal) {
			this._interValCounter = 0
			this.calValue()
		}
	}
	dispose(){
		this.disposed = true
		this.stopDetect()
		this._notifyList.length = 0
		this._callBackList.length = 0
	}
}

